Глава 5

Проектирование Web-приложения

Вне зависимости от проекта процесс разработки программного обеспечения проходит одни и те же основные стадии: исследование требований к системе, постановка задачи, выбор инструментальных средств, кодирование, тестирование работающей системы и ее сопровождение. Что касается инструментальных средств, то наш выбор остановлен на ColdFusion.

Постановка задачи

Предположим, нам поступил заказ на разработку сайта — круизы и экскурсии по достопримечательностям любимого города. Постановка задачи требует ответов на целый ряд вопросов.

Ответ: электронный бизнес в культурно-развлекательной сфере.

Знание общей задачи приложения помогает не отклоняться от заданной цели. Ответ на этот вопрос поможет установить критерии для оценки требований к функциональным возможностям продукта.

Ответ: привлечение туристов, ознакомление с возможными круизами и экскурсиями, бронирование и распространение билетов.

Ответ: представители общественности, имеющие желание и возможность путешествовать.

Существуют разные способы построения базы данных для "мировой паутины". Знание состава аудитории позволит решить, какие меры безопасности принять, какие возможности клиентской части использовать и т. п.

Здесь мы не дадим вам четкий ответ, т. к. это могут быть разные порталы или специализированные сайты, предлагающие подобные услуги. От ответа на этот вопрос многое зависит.

Ответ: таблицы расписаний, примечание по каждому круизу и экскурсии с фотографиями и пояснениями, цены, реклама туристических агентств, прогноз погоды, формы заказов и т. п.

Существует еще целый ряд дополнительных вопросов, ответив на которые можно получить более полную картину будущего приложения. Например, какая потребуется пропускная способность? Производится ли наращивание базы данных при помощи Web-интерфейса? Кто будет отвечать за информационное содержимое? Кто будет отвечать за поддержание работоспособности Web-сервера? Каковы требования к безопасности? На что следует обратить внимание при тестировании? И т. д.

Бизнес-правила

Прежде чем разработать базу данных, следует сформулировать правила, позволяющие уточнить общие требования к информационной модели. Назовем такие правила бизнес-правилами, которые в нашем случае могут быть следующими:

  1. Стоимость круизов или экскурсий не зависит от времени суток, дней недели и времени года.
  2. Стоимость круизов и экскурсий зависит от возраста туристов (взрослые, дети и престарелые люди).
  3. Один и тот же маршрут обслуживается однотипным транспортным средством.
  4. Посадочные места не нумеруются и резервируются по мере появления пассажиров.
  5. Периодичность совершения круизов и экскурсий зависит от дней недели (будни, выходные и праздники) и времени года (сезонный режим).
  6. Все круизы и экскурсии, совершаемые в рабочие дни недели, дублируются в выходные и праздничные дни, но круизы и экскурсии, запланированные в выходные и праздничные дни, необязательно совершаются в рабочие дни.
  7. За два часа до отправления бронирование билетов прекращается.
  8. Возвращение в продажу забронированных билетов заканчивается за час до отправления.
  9. При регистрации электронный адрес является входным именем пользователя (Login ID).
  10. При бронировании билетов все денежные расчеты производятся через кредитные карточки в соответствии с правилами банковских операций. Для этой цели используются услуги сторонней фирмы.

Теперь, когда задача определена, сформулированы бизнес-правила, можно начать разработку базы данных.

Разработка базы данных

Процесс создания информационной модели начинается с формулирования концептуальных требований, которые могут определяться также для некоторых задач, в ближайшее время не планируемых для реализации. Это может несколько повысить трудоемкость работы, однако поможет наиболее полно учесть все нюансы функциональности, требуемой для разрабатываемой системы, и снизить вероятность ее переделки в дальнейшем.

Концептуальная модель представляет объекты и их взаимосвязи без указания способов их физического хранения.

Таким образом, концептуальная модель является, по существу, моделью предметной области. При проектировании концептуальной модели все усилия разработчика должны быть направлены в основном на структуризацию данных и выявление взаимосвязей между ними без рассмотрения особенностей реализации и вопросов эффективности обработки. Проектирование концептуальной модели основано на анализе решаемых задач обработки данных. Концептуальная модель включает описания объектов и их взаимосвязей, представляющих интерес в рассматриваемой предметной области и выявляемых в результате анализа данных. Здесь имеются в виду данные, используемые как в уже разработанных прикладных программах, так и в тех, которые только будут реализованы.

Концептуальная модель транслируется затем в модель данных, совместимую с выбранной СУБД. Возможно, что отраженные в концептуальной модели взаимосвязи между объектами окажутся впоследствии нереализуемыми средствами выбранной СУБД. Это потребует изменения концептуальной модели. Версия концептуальной модели, которая может быть обеспечена конкретной СУБД, называется логической моделью.

Логическая модель отражает логические связи между элементами данных вне зависимости от их содержания и среды хранения. Логическая модель данных может быть реляционной, иерархической или сетевой. Пользователем выделяются подмножества этой логической модели, называемые внешними моделями (в некоторых источниках их также называют подсхемами), отражающие их представления о предметной области. Внешняя модель соответствует представлениям, которые пользователи получают на основе логической модели. Логическая модель отображается в физическую память, такую, как диск, лента или иной носитель информации.

Физическая модель, определяющая размещение данных, методы доступа и технику индексирования, называется внутренней моделью системы.

Внешние модели никак не связаны с типом физической памяти, в которой будут храниться данные с методами доступа к этим данным. Это положение отражает первый уровень независимости данных. С другой стороны, если концептуальная модель способна учитывать расширение требований к системе в будущем, то вносимые в нее изменения не должны оказывать влияния на существующие внешние модели. Это второй уровень независимости данных. Важно помнить, что построение логической модели обусловлено требованиями используемой СУБД.

Все актуальные требования предметной области и адекватные им "скрытые" требования на стадии проектирования должны найти свое отражение в концептуальной модели. Конечно, нельзя предусмотреть все возможные варианты использования и изменения базы данных. Но в большинстве предметных областей такие основные данные, как объекты и их взаимосвязи, относительно стабильны. Меняются только информационные требования, т. е. способы использования данных для получения информации.

Степень независимости данных определяется тщательностью проектирования базы данных. Всесторонний анализ объектов предметной области и их взаимосвязей минимизирует влияние изменения требований к данным в одной программе на другие программы. В этом и состоит всеобъемлющая независимость данных.

Основное различие между указанными выше тремя типами моделей данных (концептуальной, логической и физической) состоит в способах представления взаимосвязей между объектами. При проектировании БД мы воспользуемся одним из CASE-инструментов.

Итак, будем последовательны, в результате анализа поставленной задачи и обработки требований составим концептуальную модель. Начнем с определения объектов (сущностей) и взаимосвязей между ними.

Перечень сущностей:

На рис. 5.1 представлена упрощенная схема информационной модели с определением взаимосвязей.

На следующем этапе зададим атрибуты каждой сущности и укажем первичные ключи. Не будем углубляться в теорию построения базы данных, скажем только, что этого требуют правила построения базы данных.

Рис. 5.1. Упрощенная схема информационной модели с определением взаимосвязей

Наступило время привести модель к требуемому уровню нормальной формы. Приведение модели к требуемому уровню нормальной формы является основой построения реляционной базы данных и представляет собой набор критериев, которыми следует руководствоваться при проектировании реляционной БД. Перечислим три нормальные формы таблиц.

Первая нормальная форма означает такую структуру таблицы, в которой не могут находиться повторяющиеся поля данных.

Вторая нормальная форма имеет отношение к строкам, в которых каждый столбец функционально зависит от первичного ключа.

Третья нормальная форма имеет отношение к тем записям, которые соответствуют второй нормальной форме и, кроме того, не содержат каких-либо транзитивных зависимостей. Транзитивная зависимость возникает, когда в таблице находится столбец, который, не являясь ключом, описывает другие столбцы.

Сформулируем основные правила, которым нужно следовать при построении базы данных.

С учетом вышеизложенного переведем нашу концептуальную модель в физическую. Причем используемый нами CASE-инструмент PowerDesigner DataArchitect корпорации Sybase позволяет генерировать физическую модель автоматически для большинства серверов баз данных. Отдавая дань корпорации Sybase, сгенерируем нашу базу под Sybase SQL Anywhere.

Чаше всего на этапе физического проектирования производятся меры по обеспечению целостности базы данных. В СУБД целостность данных обеспечивается набором специальных предложений, называемых ограничениями целостности. Ограничение целостности — это набор определенных правил, которые устанавливают допустимость данных и связей между ними.

Ограничения целостности, в свою очередь, могут относиться к разным объектам БД: атрибутам (полям), записям, отношениям, связям между ними и т. д. Для реализации ограничений целостности, имеющих отношение к записи, таблицам или связям между ними, в СУБД используются триггеры. Как конкретно реализуются подобные триггеры, мы не будем рассматривать отдельно и оставим на самостоятельное изучение.

Физическое описание модели

В следующих разделах приведен отчет для созданной нами базы данных CRUISE.

Приведем сокращения:

Таблицы (Tables)

В табл. 5.1—5.3 приведено описание таблицы DESTINATION.

Таблица 5.1. Список полей для таблицы DESTINATION

Имя поля

Описание

Тип данных

P

М

Key des

Key destination (Уникальный ключ пункта назначения)

Integer

Да

Да

Name des

Name destination (Наименование пункта назначения)

Varchar (100)

Нет

Да

Photo des

Photo destination (Фотография пункта назначения)

Varchar (100)

Нет

Нет

Note des

Note destination (Примечание)

Long varchar

Нет

Нет

 

Таблица 5.2. Список индексов для таблицы DESTINATION

Название индекса

Р

F

и

С

Индексируемое поле

Сортировка

DESTINATION PK

Да

Нет

Да

Нет

Key des

ASC (По возрастанию)

 

Таблица 5.3. Список связей для таблицы DESTINATION

Связь для таблицы

Первичный ключ

Вторичный ключ

ROUTE

Key des

Key des

В табл. 5.4—5.6 приведено описание таблицы ROUTE.

 

Таблица 5.4. Список полей для таблицы ROUTE

Имя поля

Описание

Тип данных

P

М

Key rou

Key route (Уникальный ключ мар-шрута)

Integer

Да

Да

Key tou

Key tour (Ключ круиза)


Нет

Нет

TimeMovDep ToDes rou Time of moving from a point of Integer departure up to destination (minute) (Время перемещения от пункта отправления до текущего пункта в минутах) Integer Нет Да

Key des

Key destination (Ключ пункта назначения)

Integer

Нет

Нет

 

Таблица 5.5. Список индексов для таблицы ROUTE

Название индекса

P

F

U

С

Индексируемое поле

Сортировка

ROUTE_PK

Да

Нет

Да

Нет

Key rou

ASC (По возрастанию)

tou to rou FK

Нет

Да

Нет

Нет

Key tou

ASC (По возрастанию)

des to rou FK

Нет

Да

Нет

Нет

Key des

ASC (По возрастанию)

 

Таблица 5.6. Список связей для таблицы ROUTE

Связь для таблицы

Первичный ключ

Вторичный ключ

DESTINATION

TOUR

Key des

Key tou

Key des

Key tou

В табл. 5.7—5.9 содержится описание таблицы SCHEDULE.

 

Таблица 5.7. Список полей для таблицы SCHEDULE

Имя поля

Описание

Тип

P

М

Key sch

Key schedule (Уникальный ключ расписания)

Integer

Да

Да

Key sea

Key season (Ключ сезона)

Integer

Нет

Да

Key tou

Key tour (Ключ круиза)

Integer

Нет

Нет

TimeDepart sch

Departure time (Время отправления)

Time

Нет

Да

ChBoxWorkDay sch

Check box workday (Признак рабочего дня)

Numeric (1)

Нет

Нет

 

Таблица 5.8. Список индексов для таблицы SCHEDULE

Название индекса

P

F

U

С

Индексируемое поле

Сортировка

SCHEDULE PK

Да

Нет

Да

Нет

Key sch

ASC (По возрастанию)

sea to sch FK

Нет

Да

Нет

Нет

Key sea

ASC (По возрастанию)

tou to sch_FK

Нет

Да

Нет

Нет

Key tou

ASC (По возрастанию)

 

Таблица 5.9. Список связей для таблицы SCHEDULE

Связь для таблицы

Первичный ключ

Вторичный ключ

SEASON

TOUR

TICKET

Key sea

Key tou

Key sch

Key sea

Key tou

Key sch

В табл. 5.10—5.12 приведено описание таблицы SEASON.

 

Таблица 5.10. Список полей для таблицы SEASON

Имя поля

Описание

Тип данных

P

M

Key sea

Key season (Уникальный ключ сезона)

Integer

Да

Да

Begin sea

Beginning of a season (Дата начало сезона)

Date

Нет

Да

End sea

The ending of a season (Дата окончания сезона)

Date

Нет

Да

 

Таблица 5.11. Список индексов для таблицы SEASON

Название индекса

Р

F

и

С

Индексируемое поле

Сортировка

SEASON PK

Да

Нет

Да

Нет

Key sea

ASC (По возрастанию)

 

Таблица 5.12. Список связей для таблицы SEASON

Связь для таблицы

Первичный ключ

Вторичный ключ

SCHEDULE

Key sea

Key sea

В табл. 5.13—5.15 содержится описание таблицы TICKET.

Таблица 5.13. Список полей для таблицы TICKET

Имя поля

Описание

Тип данных

P

M

Key tic

Key ticket (Уникальным ключ билета)

Integer

Да

Да

Key tou

Key tour (Ключ круиза)

Integer

Нет

Нет

Key tra

Key traveler (Ключ путешественника)

Integer

Нет

Да

Key sch

Key schedule (Ключ расписания)

Integer

Нет

Нет

DateOrder tic

Date of the order (Дата заказа)

Time stamp

Нет

Да

 

Таблица 5.14. Список индексов для таблицы TICKET

Название индекса

P

F

U

С

Индексируемое поле

Сортировка

TICKET PK

Да

Нет

Да

Нет

Key tic

ASC (По возрастанию)

tou to tic FK

Нет

Да

Нет

Нет

Key tou

ASC (По возрастанию)

tra to tic FK

Нет

Да

Нет

Нет

Key tra

ASC (По возрастанию)

sch to tic FK

Нет

Да

Нет

Нет

Key sch

ASC (По возрастанию)

 

Таблица 5.15. Список связей для таблицы TICKET

Связь для таблицы

Первичный ключ

Вторичный ключ

SCHEDULE TOUR TRAVELER

Key sch Key tou Key_tra

Key sch Key tou Key tra

В табл. 5.16—5.18 приведено описание таблицы TOUR.

 

Таблица 5.16. Список полей для таблицы TOUR

Имя поля

Описание


Тип данных

P

М

Key_tou

Key tour круиза)

(Уникальный ключ

Integer

Да

Да

 

Имя поля

Описание

Тип данных

P

М

Name tou

Name tour (Наименование круиза)

Varchar (100)

Нет

Да

PointDepart tou

Point of departure (Пункт отправления)

Varchar (100)

Нет

Да

NumLandingPlaces tou

Number of landing places (Число посадочных мест)

Numeric (4,0)

Нет

Да

Time tou

Time in tour, hours (Время в пути, в часах)

Numeric (4,2)

Нет

Да

CostAdult tou

Cost for adults, $ (Стои-

Numeric (6,2)

Нет

Да


мость круиза для взрослых)




CostChdldren tou

Cost for children, $ (Стоимость круиза для детей)

Numeric (6,2)

Нет

Да

CostSenior tou

Cost for senior citizens, $ (Стоимость круиза для пожилых людей)

Numeric (6,2)

Нет

Да

Photo tou

Photo tour (Фотография круиза)

Varchar (100)

Нет

Нет

Note tou

Note tour (Примечание)

Long varchar

Нет

Нет

 

Таблица 5.17. Список индексов для таблицы TOUR

Название индекса

Р

F

и

С

Индексируемое поле

Сортировка

TOUR РК

Да

Нет

Да

Нет

Key tou

ASC (По возрастанию)

 

Таблица 5.18. Список связей для таблицы TOUR

Связь для таблицы

Первичный ключ

Вторичный ключ

ROUTE

SCHEDULE

TICKET

Key tou

Key tou

Key tou

Key tou

Key tou

Key tou

В табл. 5.19—5.21 приведено описание таблицы TRAVELER.

 

Таблица 5.19. Список полей для таблицы TRAVELER

Имя поля

Описание

Тип данных

P

M

Key tra

Key traveler (Уникальный ключ путешественника)

Integer

Да

Да

FirstName tra

First name (Имя)

Varchar (20)

Нет

Да

Middlelnitial_tra

Middle initial (Инициал отчества)

Varchar (1)

Нет

Нет

LastName_tra

Last name (Фамилия)

Varchar (20)

Нет

Да

EMail tra

E-Mail Address (Электронный адрес)

Varchar (50)

Нет

Да

Password tra

Pssword traveler (Пароль)

Varchar (20)

Нет

Да

PhoneNum tra

Phone number (Телефон)

Varchar (14)

Нет

Нет

Gender tra

Gender (Пол)

Numeric (1)

Нет

Нет

Birthday tra

Date of birth (Дата рождения)

Date

Нет

Нет

 

Таблица 5.20. Список индексов для таблицы TRAVELER

Название индекса

Р

F

и

С

Индексируемое поле

Сортировка

TRAVELER_PK

Да

Нет

Да

Нет

Key tra

ASC (По возрастанию)

 

Таблица 5.21. Список связей для таблицы TRAVELER

Связь для таблицы

Первичный ключ

Вторичный ключ

TICKET

Key tra

Key tra

 

Связи (References)

В табл. 5.22 содержится описание связей базы данных CRUISE.

 

Таблица 5.22. Список связей базы данных CRUISE

Имя связи

Код связи

Главное поле из таблицы

Подчиненное поле из таблицы

Des to rou

Sch to tic

Sea_to_sch

des to rou

sch to tic

sea to._sch

DESTINATION

SCHEDULE

SEASON

ROUTE

TICKET

SCHEDULE

 

Имя связи

Код связи

Главное поле из таблицы

Подчиненное поле из таблицы

Тоu to rou

tou to rou

TOUR

ROUTE

Тоu to sch

tou to sch

TOUR

SCHEDULE

Тоu to tic

tou to tic

TOUR

TICKET

Tra to tic

tra to tic

TRAVELER

TICKET

 

Триггеры (Triggers)

Заметим, что триггер является мощным инструментом контроля за изменением данных в БД, а также помогает автоматизировать операции, которые должны выполняться в определенных случаях.

Триггеры — это предварительно определенное действие или последовательность действий, автоматически осуществляемых при выполнении операций обновления, добавления или удаления данных.

В табл. 5.23 приведен список триггеров базы данных CRUISE.

Таблица 5.23. Список триггеров для базы данных CRUISE

Таблица

Триггер

Определен пользователем

ROUTE

tib route

Нет

SCHEDULE

tib schedule

Нет

TICKET

tib_ticket

Нет

Далее представлены триггеры tib_route, tib_scheduie и tib_ticket, сформированные автоматически после генерации физической модели базы данных.

Введем обозначения:

Листинг 5.1 содержит код триггера tib_route.

Листинг 5.1. Код триггера tib_route

% Before insert trigger "tib_route" for table "ROUTE"

create trigger tib route before insert on ROUTE

referencing new as new_ins for each row begin

declare user_defined_exception exception for SQLSTATE '99999';

declare insert child parent exist exception exception for SQLSTATE

'99991';

declare found integer;

% Parent "TOUR" must exist when inserting a child in "ROUTE"

if (new_ins.Key_tou is not null) then

begin

set found = 0;

select 1

into found

from dummy

where exists (select 1

from TOUR

where Key_tou = new_ins.Key_tou);

if found <> 1 then

signal insert_child_parent_exist_exception

end if; end end if;

% Parent "DESTINATION" must exist when inserting a child in "ROUTE"

if (new_ins.Key_des is not null) then

begin

set found = 0;

select 1

into found

from dummy

where exists (select 1

from DESTINATION where Key_des = new_ins.Key_des);

if found <> 1 then

signal insert_child_parent_exist_exception end if;

end

end if; exception

when insert_child_parent_exist_exception then

message 'Error: Trigger(tib_route) of table ROUTE';

message ' Parent code must exist when inserting a child!';

signal user_defined_exception; when others then

message 'Exception in before insert trigger(tib_route) of table ROUTE1;

resignal; end

Введем обозначения:

Листинг 5.2 содержит код триггера tib_scheduie.

Листинг 5.2. Код триггера tib_schedule

% Before insert trigger "tib_schedule"

for table "SCHEDULE"

create trigger tib_schedule before insert on SCHEDULE referencing new as new_ins for each row begin

declare user_defined_exception exception for SQLSTATE '99999';

declare insert_child_parent_exist_exception exception for SQLSTATE '99991';

declare found integer;

% Parent "SEASON" must exist when inserting a child in "SCHEDULE"

if (new_ins.Key_sea is not null) then

begin

set found = 0; select 1

into found from dummy where exists (select 1

from SEASON

where Key_sea = new_ins.Key_sea) ;

if found <> 1 then

signal insert_child_parent_exist_exception

end if; end end if;

% Parent "TOUR" must exist when inserting a child in "SCHEDULE"

if (new_ins.Key_tou is not null) then

begin

set found = 0;

select 1 into found from dummy where exists (select 1

from TOUR

where Key tou = new ins.Key tou);

if found <> 1 then

signal insert_child_parent_exist_exception end if;

end

end if; exception when insert_child_parent_exist_exception then

message 'Error: Trigger(tib_schedule) of table SCHEDULE';

message ' Parent code must exist when inserting a child!';

signal user_defined_exception; when others then

message 'Exception in before insert trigger(tib_schedule) of table SCHEDULE';

resignal;

end;

Введем обозначения:

В листинге 5.3 приведен код триггера tib_ticket.

ЛИСТИНГ 5.3. КОД триггера tib_ticket

% Before insert trigger "tib_ticket" for table "TICKET"

create trigger tib_ticket before insert on TICKET referencing new as new ins for each row begin

declare user_defined_exception exception for SQLSTATE '99999';

declare insert_child_parent_exist_exception exception for SQLSTATE '99991';

declare found integer;

% Parent "TOUR" must exist when inserting a child in "TICKET"

if (new_ins.Key_tou is not null) then

begin

set found = 0; select 1

into found from dummy where exists (select 1

from TOUR

where Key_tou = new_ins.Key_tou); if found <> 1 then

signal insert_child_parent_exist_exception end if;

end end if;

% Parent "TRAVELER" must exist when inserting a child in "TICKET"

if (new_ins.Key_tra is not null) then

begin

set found = 0;

select 1

into found from dummy where exists (select 1

from TRAVELER

where Key_tra = new_ins.Key_tra);

if found <> 1 then

signal insert_child_parent_exist_exception

end if; end end if;

% Parent "SCHEDULE" must exist when inserting a child in "TICKET"

if (new_ins.Key_sch is not null) then

begin

set found = 0; select 1

into found from dummy where exists (select 1

from SCHEDULE

where Key_sch = new_ins.Key sen);

if found <> 1 then

signal insert_child_parent_exist_exception

end if;

end

end if;

exception when insert_child_parent_exist_exception then

message 'Error: Trigger(tib_ticket) of table TICKET';

message ' Parent code must exist when inserting a child!';

signal user_defined_exception;

when others then

message 'Exception in before insert trigger(tib_ticket) of table TICKET';

resignal;

end

Дизайн проекта

Как вы помните, перед нами поставлена задача — разработка сайта для предоставления информации о круизах и экскурсиях. После ответа на ряд ключевых вопросов и создания базы данных для рассматриваемой задачи наступает время спроектировать непосредственно сам сайт, тщательно продумав его дизайн.

Web-дизайн — определенно творческий процесс: здесь вы можете проявить свои художественные способности, причем, как показывает практика, необязательно иметь художественное образование. Сейчас существует достаточно много программных средств, позволяющих работать с графикой, обрабатывать фотографии использовать всевозможные шрифты. Однако чувство меры и вкус никогда не помещают. И если вам не довелось прослушать курс лекций по Web-дизайну, то позвольте дать несколько советов:

В разных источниках можно прочитать, что главный критерий, на который следует ориентироваться в процессе разработки страниц, — это удобство конечного пользователя. И с этим трудно не согласиться.

Одним из первых шагов является набросок "карты сайта". Это графическая схема, показывающая путь продвижения посетителя по сайту. Ваша карта должна включать в себя каждую его страницу и то, в какой зависимости они находятся относительно других страниц.

Для нашего случая определим шесть основных пунктов, характеризующих костяк сайта:

Далее определим, следует ли нам использовать так называемую заглавную страницу (splash page). Заглавная страница (или заставка) чаще всего применяется, если к потенциальному посетителю существует ряд вопросов, или возникает необходимость проинформировать посетителя о чем-либо, например, выбор языка или кодировки страниц, демонстрация Flash-анимации, предупреждение о том или ином соглашении при использовании данных текущего ресурса, демонстрация счетчика посещений, показ рейтинговых форм сайта и т. д.

Единственное, для чего следует использовать заглавную страницу в нашем случае, — это выбор языка просмотра страницы, поскольку среди путешественников достаточно часто встречаются иностранные туристы, предпочитающие читать на родном языке. Но в данном случае есть предложение перейти к разработке английской версии Web-приложения. (Разработку заглавной страницы разберем при изучении cookies в главе 7.)

Любая Web-страница содержит определенный набор стандартных элементов, таких как заголовок, логотип, элементы навигации, основная область страницы, подзаголовок и т. д. Компоновка этих элементов, проектирование их взаимного расположения и составляют одну из главных задач Web-мастера.

Еще одним немаловажным шагом является выбор используемых технологий при кодировании страниц.

Неспроста мы уделили значительное время разработке базы данных, т. к. некоторые наши страницы в силу своей специфики будет проще формировать "на лету", используя саму базу данных, например для составления расписания круизов.

Для упрощения работы с набором стилей Web-проекта как при создании, так и при дальнейшей его поддержке предполагаем использование технологии каскадных таблиц стилей (Cascading Style Sheets, CSS).

Также в отдельных случаях планируем использование Dynamic HTML и JavaScript. Мы уже не оговариваем, что ключевым моментом при кодировании документов будет язык CFML.

После определенных усилий по части выбора собственного стиля и компоновке основных элементов страницы, мы пришли к результату.

Следуя изложенным ранее советам, хочется отметить, что фотография с видом статуи свободы — также результат собственного творчества.

В итоге последовательность работ по проектированию Web-приложения сводится к следующим действиям:

Имея достаточный опыт работы по проектированию приложений, отметим, что, чуть ли ни каждый этап разработки Web-приложения следует согласовывать с заказчиком.

В приложении 1 представлены коды основных файлов в рамках проекта "My-Line Cruises".